﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.ComponentModel;
using Terralever.Facebook.UI.Design;
using System.Web.UI.WebControls;

namespace Terralever.Facebook.UI.FbmlControls
{
    /// <summary>
    /// Provides common functionality for the <see>Age18Plus</see> and <see>Age21Plus</see> controls.
    /// </summary>
    [ParseChildren(ChildrenAsProperties = true)]
    [Designer("Terralever.Facebook.UI.Design.FbmlControls.MinimumAgeControlDesigner, " + Constants.DESIGNER_LIB)]
    [PersistChildren(false)]
    public abstract class MinimumAgeControl : FbmlControl, INamingContainer
    {
        private AgeTemplateContainer m_overContainer, m_notContainer;
        private ITemplate m_isTemplate, m_notTemplate;

        private void CreateContents()
        {
            ClearContents();

            if (m_overContainer == null)
            {
                m_overContainer = new AgeTemplateContainer(this);
                if (m_isTemplate != null)
                {
                    m_isTemplate.InstantiateIn(m_overContainer);
                }
                this.Controls.Add(m_overContainer);
            }
            else if (m_isTemplate != null)
            {
                this.m_isTemplate.InstantiateIn(this.m_overContainer);
            }

            if (m_notContainer == null)
            {
                m_notContainer = new AgeTemplateContainer(this);
                if (m_notTemplate != null)
                    this.m_notTemplate.InstantiateIn(this.m_notContainer);
                Controls.Add(m_notContainer);
            }
            else if (m_notTemplate != null)
            {
                this.m_notTemplate.InstantiateIn(this.m_notContainer);
            }
        }

        internal void ClearContents()
        {
            if (m_overContainer != null)
                m_overContainer.Controls.Clear();

            m_overContainer = null;

            if (m_notContainer != null)
                m_notContainer.Controls.Clear();

            m_notContainer = null;

            Controls.Clear();
        }

        /// <summary>
        /// Gets or sets the template that should be used when the user is old enough to view the content protected by the control.  This property is required.
        /// </summary>
        [TemplateContainer(typeof(AgeTemplateContainer))]
        [Browsable(false)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DefaultValue(null)]
        [TemplateInstance(TemplateInstance.Single)]
        public ITemplate IsOfAgeTemplate
        {
            get { return m_isTemplate; }
            set
            {
                m_isTemplate = value;
                if (m_isTemplate != null)
                {
                    CreateContents();
                }
            }
        }

        /// <summary>
        /// Gets or sets the template that should be used when the user is too young to view the content protected by the control.
        /// </summary>
        [TemplateContainer(typeof(AgeTemplateContainer))]
        [Browsable(false)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DefaultValue(null)]
        [TemplateInstance(TemplateInstance.Single)]
        public ITemplate IsNotOfAgeTemplate
        {
            get { return m_notTemplate; }
            set
            {
                m_notTemplate = value;
                if (m_notTemplate != null)
                    CreateContents();
            }
        }

        /// <inheritdoc />
        protected override void Render(HtmlTextWriter writer)
        {
            if (m_overContainer == null)
                throw new RequiredFbmlAttributeNotSetException("The <IsOfAgeTemplate> template is missing and is required.");

            CreateContents();

            writer.RenderBeginTag(ElementName);
            m_overContainer.RenderControl(writer);
            if (m_notTemplate != null)
            {
                writer.RenderBeginTag(FbmlConstants.FB_ELSE);
                m_notContainer.RenderControl(writer);
                writer.RenderEndTag();
            }
            writer.RenderEndTag();
        }

        private DesignerDisplayMode m_mode = DesignerDisplayMode.LogicTestPassed;
        /// <summary>
        /// Gets or sets a design-time setting specifying which template to render.
        /// </summary>
        /// <exception cref="InvalidEnumArgumentException">Thrown if <paramref name="value"/> is not a member of the 
        /// <see cref="Terralever.Facebook.UI.Design.DesignerDisplayMode">DesignerDisplayMode</see> enumeration.</exception>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public DesignerDisplayMode DesignerDisplayMode
        {
            get { return m_mode; }
            set
            {
                if (!Enum.IsDefined(typeof(DesignerDisplayMode), value))
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(DesignerDisplayMode));

                m_mode = value;
            }
        }
    }
}
